package com.abcode.nettyclient.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.timeout.IdleStateHandler;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

//@Component
public class NettyClient {
    private EventLoopGroup group;
    private Bootstrap bootstrap;
    private Channel channel;

    public void start222() {
        group = new NioEventLoopGroup();
        bootstrap = new Bootstrap();
        bootstrap.group(group)
                 .channel(NioSocketChannel.class)
                 .handler(new ChannelInitializer<SocketChannel>() {
                     @Override
                     protected void initChannel(SocketChannel ch) throws Exception {
                         ch.pipeline().addLast(new StringEncoder(), new StringDecoder(), new NettyClientHandler());
                     }
                 });
        connect();
    }
    @PostConstruct
    private void start() throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        try {
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .remoteAddress("localhost", 9999)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            /**
                             *  0 表示禁用
                             * readerIdleTime读空闲超时时间设定，如果channelRead()方法超过readerIdleTime时间未被调用则会触发超时事件调用userEventTrigger()方法；
                             *
                             * writerIdleTime写空闲超时时间设定，如果write()方法超过writerIdleTime时间未被调用则会触发超时事件调用userEventTrigger()方法；
                             *
                             * allIdleTime所有类型的空闲超时时间设定，包括读空闲和写空闲；
                             */
                            socketChannel.pipeline().addLast(new IdleStateHandler(20, 10, 0));
                            socketChannel.pipeline().addLast(new ObjectEncoder());
                            socketChannel.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                            socketChannel.pipeline().addLast(new NettyClientHandler());
                        }
                    });
            ChannelFuture future = bootstrap.connect("localhost", 9999).sync();
            if (future.isSuccess()) {
                channel = future.channel();
                System.out.println("connect server  成功---------");
            }
            //给关闭通道进行监听
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
     private void connect() {
        ChannelFuture future = bootstrap.connect("localhost", 9999);
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    channel = future.channel();
                    System.out.println("Connected to server!");
                } else {
                    System.out.println("Failed to connect to server.");
                    future.cause().printStackTrace();
                }
            }
        });
    }
     public void send(String message) {
        if (channel != null && channel.isActive()) {
            channel.writeAndFlush(message);
        }
    }
     @PreDestroy
    public void stop() {
        group.shutdownGracefully();
    }
}